using System;
using System.Collections.Generic;

namespace IWS.Lib.SingleSignOn
{
	/// <summary>
	/// A session object is used to track authenticated applications and users to a web service. 
	/// </summary>
	public class Session
	{
		Guid m_ID;
		Guid m_UserID;
		DateTime m_LastActiveDate;
		DateTime m_ExpirationDate;
		string m_Key;

		/// <summary>
		/// Create a new session
		/// </summary>
		public Session()
		{
			init();
		}

		/// <summary>
		/// Create a new instance and preload data by ID.
		/// </summary>
		/// <param name="id"></param>
		public Session(Guid id)
		{
			init();
			Load(id);
		}
		/// <summary>
		/// Create a new instance of sessing using a session key
		/// </summary>
		/// <param name="key">Session key</param>
		public Session(string key)
		{
			init();
			this.Load(key);
		}


		private void init()
		{
			 m_ID = Guid.Empty;
			 m_UserID = Guid.Empty;
			 m_LastActiveDate = new DateTime(1900,1,1,0,0,0,0);
			 m_ExpirationDate = new DateTime(1900,1,1,0,0,0,0);
			 m_Key = "";
		}


		#region Properties
		/// <summary>
		/// DB Identifier for this sessoin
		/// </summary>
		public Guid ID
		{
			get {return m_ID;}
			set {m_ID = value;}
		}
		/// <summary>
		/// Currently associated user.
		/// </summary>
		public Guid UserID
		{
			get {return m_UserID;}
			set {m_UserID = value;}
		}
		/// <summary>
		/// Date and time of last activity.
		/// </summary>
		public DateTime LastActiveDate
		{
			get {return m_LastActiveDate;}
			set {m_LastActiveDate = value;}
		}
		/// <summary>
		/// Currently not used. 
		/// </summary>
		public DateTime ExpirationDate
		{
			get {return m_ExpirationDate;}
			set {m_ExpirationDate = value;}
		}
		/// <summary>
		/// Session key used as a pass code to access the webservices. 
		/// </summary>
		public string Key
		{
			get {return m_Key;}
			set {m_Key = value;}
		}
		#endregion

		/// <summary>
		/// Load this session
		/// </summary>
		public void Load(Guid id)
		{
			Session data = Instance.getDataProvider().LoadSession(id);
			this.ID = data.ID;
			this.UserID = data.UserID;
			this.LastActiveDate = data.LastActiveDate;
			this.ExpirationDate = data.ExpirationDate;
			this.Key = data.Key;
		}
		/// <summary>
		/// Load this session by its key
		/// </summary>
		public void Load(string key)
		{
			Session data = Instance.getDataProvider().LoadSession(key);
			this.ID = data.ID;
			this.UserID = data.UserID;
			this.LastActiveDate = data.LastActiveDate;
			this.ExpirationDate = data.ExpirationDate;
			this.Key = data.Key;
		}

		/// <summary>
		/// Save this session
		/// </summary>
		/// <param name="id"></param>
		public void Save()
		{
			if (this.ID.Equals(Guid.Empty))
			{
				this.ID = Guid.NewGuid();
			}
			Instance.getDataProvider().SaveSession(this);
		}

		/// <summary>
		/// Remove this session
		/// </summary>
		/// <param name="id"></param>
		public void Remove()
		{
			Instance.getDataProvider().RemoveSession(this.ID);
		}

		/// <summary>
		/// Check if this session already exists.
		/// </summary>
		/// <param name="id">Session ID</param>
		public bool Exists()
		{
			return Session.Exists(this.ID);
		}

		/// <summary>
		/// Validates the current session. 
		/// </summary>
		/// <remarks>In order for a successful validation to occur, a session must exist.</remarks>
		/// <returns></returns>
		public static bool ValidateSession(string Key)
		{
			bool success = false;
			//double check session key
			if (Session.Exists(Key)) //must exist
			{
				Session session = new Session(Key);

				session.LastActiveDate = DateTime.Now.ToUniversalTime();
				session.Save();

				success = true;
			}
			return success;
		}

		/// <summary>
		/// Intililize this instance with a new session key and expiration date. 
		/// </summary>
		public void Initialize()
		{
			this.Key = Utility.GetRandomString(50);
			while (Session.Exists(this.Key))
			{
				this.Key = Utility.GetRandomString(50);
			}
			this.LastActiveDate = DateTime.Now.ToUniversalTime();
		}

		/// <summary>
		/// Check if this session already exists.
		/// </summary>
		/// <param name="id">Session ID</param>
		public static bool Exists(Guid ID)
		{
			return Instance.getDataProvider().CountSession(ID) > 0;
		}

		/// <summary>
		/// Check if this session already exists.
		/// </summary>
		/// <param name="id">Session ID</param>
		public static bool Exists(string Key)
		{
			return Instance.getDataProvider().CountSession(Key) > 0;
		}

		/// <summary>
		/// List all Session
		/// </summary>
		public static List<Session> ListAll()
		{
			return Instance.getDataProvider().ListAllSession();
		}

	}
}
